﻿using Himp.Platform;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;

namespace Himp.Erp
{
    /// <summary>
    /// OpenApi接口
    /// </summary>
    [Area(ErpRemoteServiceConsts.ModuleName)]
    [RemoteService(Name = ErpRemoteServiceConsts.RemoteServiceName)]
    [Route("api/erp/v1/openapi")]
    [ApiVersion("1")]
    [ApiController]
    [ControllerName("openapi")]
    public class OpenApiController : ErpController
    {
        #region Services

        /// <summary>
        /// 
        /// </summary>
        public IOpenApiFuncConfigService OpenApiFuncConfigService { get; set; }

        /// <summary>
        /// 药品分类
        /// </summary>
        public IDrugCatalogTypeService DrugCatalogTypeService { get; set; }

        /// <summary>
        /// 药品厂商
        /// </summary>
        public IDrugPrdrService DrugPrdrService { get; set; }

        /// <summary>
        /// 药品目录
        /// </summary>
        public IDrugCatalogService DrugCatalogService { get; set; }

        /// <summary>
        /// 药品目录明细
        /// </summary>
        public IDrugCatalogExtService DrugCatalogExtService { get; set; }

        /// <summary>
        /// 物资入库
        /// </summary>
        public IInboundRecService InboundRecService { get; set; }

        /// <summary>
        /// 物资出库
        /// </summary>
        public IOutboundRecService OutboundRecService { get; set; }

        #endregion

        /// <summary>
        /// 接口
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [Authorize]
        public async Task<OpenApiOutput> PostAsync([FromBody] OpenApiInput input)
        {
            OpenApiOutput openApiOutput = new OpenApiOutput();
            openApiOutput.RecvTime = DateTime.Now.ToString("yyyyMMddHHmmssfff");

            try
            {
                var openApiFuncConfigList = await OpenApiFuncConfigService.GetListAsync(new OpenApiFuncConfigInput()
                {
                    FuncCode = input.InfNo
                });
                var openApiFuncConfig = openApiFuncConfigList.Items.FirstOrDefault();

                if (openApiFuncConfig == null)
                {
                    throw new UserFriendlyException("未找到有效的FuncCode");
                }

                Type openApiController = typeof(OpenApiController);
                // 获取所有属性的信息
                var property = openApiController.GetProperties().Where(p => p.Name == openApiFuncConfig.ServiceName).FirstOrDefault();

                if (property == null)
                {
                    throw new UserFriendlyException("未找到有效的接入服务");
                }

                object value = property.GetValue(this);
                Type type = value.GetType();
                MethodInfo methodInfo = type.GetMethod(openApiFuncConfig.MethodName);

                if (methodInfo == null)
                {
                    throw new UserFriendlyException("未找到有效的服务方法");
                }

                #region Input转Json对象

                List<object> parameters = new List<object>();
                object openApiInput = null;

                try
                {
                    if (input.ReqMethod == 1)
                    {
                        Type inputType = Type.GetType(openApiFuncConfig.ParameterType);
                        var genericMethods = typeof(JsonConvert).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(j => j.Name == "DeserializeObject" && j.ReturnType.Name == "T");
                        var genericMethod = genericMethods.FirstOrDefault();
                        MethodInfo concreteMethod = genericMethod.MakeGenericMethod(inputType);
                        openApiInput = concreteMethod.Invoke(null, new object[] { input.Input });
                        parameters.Add(openApiInput);
                    }
                    else if (input.ReqMethod == 2)
                    {
                        var openApiPutReq = JsonConvert.DeserializeObject<OpenApiPutReq>(input.Input);
                        Type inputType = Type.GetType(openApiFuncConfig.ParameterType);
                        var genericMethods = typeof(JsonConvert).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(j => j.Name == "DeserializeObject" && j.ReturnType.Name == "T");
                        var genericMethod = genericMethods.FirstOrDefault();
                        MethodInfo concreteMethod = genericMethod.MakeGenericMethod(inputType);
                        openApiInput = concreteMethod.Invoke(null, new object[] { openApiPutReq.Input });

                        parameters.Add(openApiPutReq.Id);
                        parameters.Add(openApiInput);
                    }
                    else if (input.ReqMethod == 3)
                    {
                        var openApiDeleteReq = JsonConvert.DeserializeObject<OpenApiDeleteReq>(input.Input);
                        parameters.Add(openApiDeleteReq.Id);
                    }
                }
                catch (Exception e)
                {
                    throw new UserFriendlyException("Input转Json对象失败");
                }

                #endregion

                #region Service方法调用

                //if (input.ReqMethod == 1)
                //{

                //}
                //else if (input.ReqMethod == 2)
                //{

                //}
                //else if (input.ReqMethod == 3)
                //{

                //}

                var task = methodInfo.Invoke(value, parameters.ToArray());

                // 确保这是一个 Task 或 Task<T>
                if (task is Task)
                {
                    // 如果是 Task<T>，获取结果
                    if (task.GetType().IsGenericType)
                    {
                        // Task<T> 类型
                        var resultProperty = task.GetType().GetProperty("Result");
                        // 等待任务完成并获取结果
                        await (Task)task; // 这里需要使用 await 以异步方式等待 Task 完成
                        var result = resultProperty.GetValue(task);
                        // 将结果对象转换为 JSON
                        string jsonResult = JsonConvert.SerializeObject(result);
                        openApiOutput.Output = jsonResult;
                    }
                }
                else
                {
                    throw new UserFriendlyException("服务方法返回不是有效Task");
                }

                #endregion

            }
            catch (Exception e)
            {
                openApiOutput.ErrMsg = e.Message;
                openApiOutput.InfStasno = -1;
                openApiOutput.ResTime = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                openApiOutput.RefMsgId = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            }

            return openApiOutput;
        }
    }

    public class OpenApiInput
    {
        /// <summary>
        /// 接口编号
        /// </summary>
        [Required]
        [StringLength(50)]
        public string InfNo { get; set; }

        /// <summary>
        /// 报文ID
        /// </summary>
        [Required]
        [StringLength(30)]
        public string MsgId { get; set; }

        /// <summary>
        /// 接口版本号
        /// </summary>
        [Required]
        [StringLength(6)]
        public string InfVerno { get; set; }

        /// <summary>
        /// 1 Post
        /// 2 Put
        /// 3 Delete
        /// </summary>
        [Required]
        public int ReqMethod { get; set; }

        /// <summary>
        /// 请求时间
        /// </summary>
        [Required]
        [StringLength(19)]
        public string ReqTime { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public Guid? InputId { get; set; }

        /// <summary>
        /// 输入
        /// </summary>
        [Required]
        public string Input { get; set; }
    }

    public class OpenApiOutput
    {
        /// <summary>
        /// 接口状态码
        /// 0  成功
        /// -1 失败
        /// </summary>
        public int InfStasno { get; set; }

        /// <summary>
        /// 接收方报文ID
        /// 链路ID
        /// 时间(14)+流水号(10)
        /// </summary>
        public string RefMsgId { get; set; }

        /// <summary>
        /// 接收时间
        /// 格式：yyyyMMddHHmmssfff
        /// </summary>
        public string RecvTime { get; set; }

        /// <summary>
        /// 响应时间
        /// 格式：yyyyMMddHHmmssfff
        /// </summary>
        public string ResTime { get; set; }

        /// <summary>
        /// 输出
        /// </summary>
        public string? Output { get; set; }

        /// <summary>
        /// 错误信息
        /// 交易失败状态下，业务返回的错误信息
        /// </summary>
        public string? ErrMsg { get; set; }

        public OpenApiOutput()
        {
            InfStasno = 0;
            ErrMsg = string.Empty;
        }
    }

    public class OpenApiDeleteReq
    {
        public Guid Id { get; set; }
    }

    public class OpenApiPutReq
    {
        public Guid Id { get; set; }

        public string Input { get; set; }
    }
}
